package com.study.config;

import com.alibaba.fastjson.JSONObject;
import com.study.entity.SysJob;
import com.study.service.SysJobService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 这个类用于启动SpringBoot时，加载作业。run方法会自动执行。
 *
 * 另外可以使用 ApplicationRunner
 *
 * @author
 */
@Slf4j
@Component
public class InitStartSchedule implements CommandLineRunner {


	@Autowired
	private SysJobService sysJobService;
	@Autowired
	private QuartzJobFactory myJobFactory;

	/**
	 * 用于程序启动时加载定时任务，并执行已启动的定时任务(只会执行一次，在程序启动完执行)
	 */
	@Override
	public void run(String... args) throws Exception {
		// 通过SchedulerFactory获取一个调度器实例
		Scheduler scheduler = new StdSchedulerFactory().getScheduler();
		// 如果不设置JobFactory，Service注入到Job会报空指针
		scheduler.setJobFactory(myJobFactory);
		// 启动调度器
		scheduler.start();

		//查询job状态为启用的
		HashMap<String, String> map = new HashMap();
		map.put("jobStatus", "1");

		List<SysJob> jobList = sysJobService.querySysJobList(map);
		if (Objects.isNull(jobList) || jobList.size() == 0) {
			log.info("系统启动，没有需要执行的任务... ...");
			return;
		}
		for (SysJob sysJob : jobList) {
			String jobClassName = sysJob.getJobName();
			String jobGroupName = sysJob.getJobGroup();
			//构建job信息
			JobDetail jobDetail = JobBuilder.newJob(getClass(sysJob.getJobClassPath()).getClass())
					.withIdentity(jobClassName, jobGroupName)
					.storeDurably()
					.withDescription("描述信息")
					.requestRecovery(true)
					.build();
			if (Objects.nonNull(sysJob.getJobDataMap())) {
				JSONObject jb = JSONObject.parseObject(sysJob.getJobDataMap());
				Map<String, Object> dataMap = (Map<String, Object>) jb.get("data");
				for (Map.Entry<String, Object> m : dataMap.entrySet()) {
					jobDetail.getJobDataMap().put(m.getKey(), m.getValue());
				}
			}
			//表达式调度构建器(即任务执行的时间)
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(sysJob.getJobCron());
			//按新的cronExpression表达式构建一个新的trigger
			CronTrigger trigger = TriggerBuilder.newTrigger()
					.withIdentity(jobClassName, jobGroupName)
					.withSchedule(scheduleBuilder)
					.startNow()
					.build();
			// 任务不存在的时候才添加
			if (!scheduler.checkExists(jobDetail.getKey())) {
				try {
					scheduler.scheduleJob(jobDetail, trigger);
				} catch (SchedulerException e) {
					log.info("创建定时任务失败" + e);
					throw new Exception("创建定时任务失败");
				}
			}
		}
	}

	public static Job getClass(String classname) throws Exception {
		Class<?> c = Class.forName(classname);
		return (Job) c.newInstance();
	}
}